<script setup>
import { ref, watch, onMounted } from "vue";
import { Promotion } from "@element-plus/icons-vue";
import ChatTimeLine from "@/components/chat/TimeLine.vue";
import ChatText from "@/components/chat/Text.vue";
import ChatImg from "@/components/chat/Img.vue";
import ChatVideo from "@/components/chat/Video.vue";
import ChatFile from "@/components/chat/File.vue";
import ChatOrder from "@/components/chat/Order.vue";
import ChatOrderTips from "@/components/chat/OrderTips.vue";
import ChatGoods from "@/components/chat/Goods.vue";
import ChatSendGoods from "@/components/chat/SendGoods.vue";
import ChatOrderMsg from "@/components/chat/OrderMsg.vue";
import ChatGraphText from "@/components/chat/GraphText.vue";
import ChatInvite from "@/components/chat/Invite.vue";
import { useMsg } from "@/store/useMsg";
import defaultHead from "@/assets/app-mj.png";
import { storeToRefs } from "pinia";
import { useSocketStore } from "@/store/useSocketStore";
import EmojBox from "@/components/EmojBox.vue";
import { fileUploadAPI } from "@/api/fileUpload";
import { saleGetChatInfo, getGoodsByStatus } from "@/api/user";
import { ElMessage, ElMessageBox } from "element-plus";
import { useUser } from "@/store/useUser";

const msgStore = useMsg();
const userStore = useUser();
const { getUserInfo } = storeToRefs(userStore);
const { getCurrentTalkInfo, currentImKey, getCurrentMsgList } = storeToRefs(msgStore);
const socketStore = useSocketStore();

const toolMenuShow = ref(false);
const showToolMneu = () => {
  toolMenuShow.value = !toolMenuShow.value;
};

// 获取聊天记录
const page = ref(1);
const pageSize = ref(20);
const msgListLoading = ref(false);
const scrollStatus = ref(false);
const getChatRecord = async () => {
  msgListLoading.value = true;
  const chatKey = currentImKey.value;
  if (!chatKey) return;
  socketStore.emit(
    "chatHistory",
    { page: page.value, pageSize: pageSize.value, imKey: currentImKey.value },
    (res) => {
      if (res.code === 200 && res.data.length > 0) {
        console.log("chatHistory", res.data);
        msgStore.addMessage(chatKey, res.data.reverse());
        if (page.value === 1 && scrollStatus.value) scrollToBottom();
        scrollStatus.value = true;
        if (page.value === 1) {
          scrollToBottom();
        }
        const total = res.total;
        const totalPage = Math.ceil(total / pageSize.value);
        if (totalPage > page.value) {
          page.value++;
        }
      }
      setTimeout(() => {
        msgListLoading.value = false;
      }, 1000);
    }
  );
};
// 添加滚动位置追踪变量
const lastScrollTop = ref(0);
// 优化后的滚动监听函数
const scrollToTop = () => {
  if (!scrollStatus.value) return;
  chatViewRef.value.addEventListener("scroll", () => {
    const currentScrollTop = chatViewRef.value.scrollTop;
    const isScrollingUp = currentScrollTop < lastScrollTop.value;

    // 更新上次滚动位置
    lastScrollTop.value = currentScrollTop;

    // 只在向上滚动且接近顶部时获取历史消息
    if (isScrollingUp && currentScrollTop < 40) {
      getChatRecord();
    }
  });
};
// 设置已读
const setRead = () => {
  const uimKey = getUserInfo.value.uimKey;
  const findNoRead = getCurrentMsgList.value.filter(
    (item) => !item.read && item.msgKey && item.from !== uimKey
  );
  if (findNoRead.length) {
    const msgKeys = findNoRead.map((item) => item.msgKey);
    socketStore.emit(
      "setRead",
      {
        to: currentImKey.value,
        msgKeys,
      },
      (setReadRes) => {
        console.log(setReadRes);
        if (setReadRes.code === 200) {
          msgStore.setMsgListRead();
        }
      }
    );
  }
};

// 获取卖家信息
const skillInfo = ref({});
const getSkillInfo = async () => {
  if (
    !getCurrentTalkInfo.value ||
    getCurrentTalkInfo.value.userType === 4 ||
    getCurrentTalkInfo.value.userType === 3
  )
    return;
  try {
    const res = await saleGetChatInfo({
      sysUserId: getCurrentTalkInfo.value.uid,
    });
    skillInfo.value = res.data;
  } catch (error) {
    console.log(error);
  }
};

const onlineServiceInfo = ref({});
watch(
  currentImKey,
  (val) => {
    if (val) {
      page.value = 1;
      // 如果是客服
      if (getCurrentTalkInfo.value?.userType === 3) {
        console.log("客服");
        msgStore.sendMessage(
          "chatMsg",
          {
            to: currentImKey.value,
            content: "为您分配在线客服中...",
            contentType: 4,
          },
          null,
          false
        );
        // 获取在线客服
        msgStore.sendMessage("onlineService", {}, (res) => {
          console.log("客服", res);
          if (res.code === 200 && res.data) {
            msgStore.sendMessage(
              "chatMsg",
              {
                to: currentImKey.value,
                content: `已为您连接技能猴子官方在线客服：${res.data.userName}`,
                contentType: 4,
              },
              null,
              false
            );
            onlineServiceInfo.value = res.data;
          } else {
            ElMessageBox.confirm(res.message, "提示", {
              confirmButtonText: "确定",
              cancelButtonText: "取消",
              type: "error",
            });
          }
        });
      }
      scrollStatus.value = false;
      getChatRecord();
      getSkillInfo();
    }
  },
  {
    immediate: true,
  }
);
watch(
  getCurrentMsgList,
  () => {
    if (page.value === 1 && !scrollStatus.value) scrollToBottom();
    setRead();
  },
  {
    deep: true,
  }
);
onMounted(() => {
  page.value = 1;
  if (getCurrentTalkInfo.value && getCurrentTalkInfo.value.userType !== 3) {
    getChatRecord();
  }
  if (getCurrentTalkInfo.value) {
    getSkillInfo();
    scrollToTop();
  }
});
// chatview滚动到底部,带滚动动画
const chatViewRef = ref(null);
const scrollToBottom = () => {
  if (scrollStatus.value && page.value !== 1) return;
  scrollStatus.value = true;
  setTimeout(() => {
    chatViewRef.value.scrollTo({
      top: chatViewRef.value.scrollHeight,
      behavior: "smooth",
    });
  }, 300);
  setTimeout(() => {
    scrollStatus.value = false;
  }, 1000);
};
// 表情弹窗
const msgText = ref("");
const emojBoxShow = ref(false);
const selectEmoj = (emoj) => {
  msgText.value += emoj;
  emojBoxShow.value = false;
};
// 发送消息
const sendMessage = () => {
  if (!msgText.value) {
    return ElMessage.warning("请输入消息内容");
  }
  let toImKey = "";
  // 如果是和客服对话
  if (getCurrentTalkInfo.value?.userType === 3) {
    if (!onlineServiceInfo.value._id) {
      return ElMessage.warning("当前不能给客服发送消息");
    } else {
      toImKey = onlineServiceInfo.value._id;
    }
  }
  console.log(toImKey);
  msgStore.sendMessage(
    "chatMsg",
    {
      to: currentImKey.value,
      toServiceImKey: toImKey,
      content: msgText.value,
      contentType: 1,
    },
    (res) => {
      if (res.code !== 200) {
        if (res.code === 1) {
          return ElMessage.success("消息已发出，对方暂时不在线。请等待回复。");
        }
        ElMessage.error(res.message);
      }
    }
  );
  msgText.value = "";
  scrollToBottom();
};
// 选择文件，上传图片
// 2: 图片 5:视频  6: 文件
const uploading = ref(false);
const selectFile = (type) => {
  uploading.value = true;
  try {
    const file = document.createElement("input");
    file.type = "file";
    const accept =
      type === 2
        ? "image/*"
        : type === 5
        ? "video/*"
        : ".pdf,.txt,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.zip,.rar";
    file.accept = accept;
    file.onchange = () => {
      const fileItem = file.files?.[0];
      // 验证文件格式
      if (type === 2) {
        if (fileItem.type.indexOf("image") === -1) {
          ElMessage.error("请上传图片文件");
          uploading.value = false;
          return;
        }
      }
      if (type === 5) {
        if (fileItem.type.indexOf("video") === -1) {
          ElMessage.error("请上传视频文件");
          uploading.value = false;
          return;
        }
      }
      if (type === 6) {
        const fileTypes = [
          "application/pdf",
          "application/msword",
          "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
          "application/vnd.ms-excel",
          "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
          "application/vnd.ms-powerpoint",
          "application/vnd.openxmlformats-officedocument.presentationml.presentation",
        ];
        if (fileTypes.indexOf(fileItem.type) === -1) {
          uploading.value = false;
          ElMessage.error("请上传支持的文件格式");
          return;
        }
      }

      console.log(fileItem);
      if (!fileItem) return;
      const formData = new FormData();
      formData.append("file", fileItem);
      fileUploadAPI(formData)
        .then((res) => {
          if (res.code === 200 && res.data.url) {
            const imgUrl = res.data.url;
            msgStore.sendMessage(
              "chatMsg",
              {
                to: currentImKey.value,
                content: imgUrl,
                contentType: type,
                exData: {
                  fileName: fileItem.name,
                  fileSize: fileItem.size,
                  fileType: fileItem.type,
                },
              },
              (res) => {
                if (res.code !== 200) {
                  ElMessage.error(res.message);
                }
              }
            );
            scrollToBottom();
          } else {
            ElMessage.error("文件上传失败");
          }
          uploading.value = false;
        })
        .catch(() => {
          uploading.value = false;
        });
    };
    file.oncancel = () => {
      uploading.value = false;
    };
    file.click();
  } catch (error) {
    console.log(error);
    uploading.value = false;
  }
};

function handleKeydown(e) {
  // 如果按下 Enter 键且没有按下 Shift 键
  if (e.key === "Enter" && !e.shiftKey) {
    e.preventDefault(); // 阻止默认的换行行为
    sendMessage(); // 调用发送消息的函数
  }
}
// 获取商品列表
const goodsList = ref([]);
const goodsLoading = ref(false);
const total = ref(0);
async function fetchGoodsList() {
  goodsLoading.value = true;
  try {
    const response = await getGoodsByStatus({
      queryStatus: 1,
      pageNum: 1,
      pageSize: 100,
    });
    goodsList.value = response.data.records;
    total.value = response.data.total;
  } catch (error) {
    console.error("获取商品列表失败:", error);
  } finally {
    goodsLoading.value = false;
  }
}
fetchGoodsList();
// 分享给当前聊天窗口
const sendToCurrentChat = (item) => {
  if (item && item.id) {
    msgStore.sendMessage(
      "chatMsg",
      {
        to: currentImKey.value,
        content: "分享服务",
        contentType: 8,
        exData: item,
      },
      (res) => {
        console.log("分享给当前聊天窗口 res", res);
      }
    );
  }
};
</script>

<template>
  <div class="window">
    <div class="chat-header" v-if="getCurrentTalkInfo && getCurrentTalkInfo.imKey">
      <el-image
        class="head"
        v-if="getCurrentTalkInfo.avatar"
        :src="getCurrentTalkInfo.avatar"
        alt=""
      >
        <template #error>
          <img class="head" :src="defaultHead" alt="" />
        </template>
      </el-image>
      <el-image v-else class="head" :src="defaultHead" alt="" />
      <div class="info">
        <span class="name">{{ getCurrentTalkInfo.userName }}</span>
        <template
          v-if="getCurrentTalkInfo.userType !== 4 && getCurrentTalkInfo.userType !== 3"
        >
          <span :class="getCurrentTalkInfo.online === 1 ? 'online' : 'offline'"
            >● {{ getCurrentTalkInfo.online === 1 ? "在线" : "离线" }}</span
          >
        </template>
      </div>
      <div
        class="tool-menu"
        v-if="getCurrentTalkInfo.userType !== 4 && getCurrentTalkInfo.userType !== 3"
      >
        <span @click="showToolMneu">●●●</span>
        <div class="menu" v-if="toolMenuShow">
          <span><img src="@/assets/menu-chat-1.png" alt="" />举报</span>
          <span><img src="@/assets/menu-chat-2.png" alt="" />拉黑</span>
        </div>
      </div>
    </div>
    <div class="chat-box">
      <div class="chat-left">
        <div class="chat-view" ref="chatViewRef">
          <span
            v-if="msgListLoading && currentImKey"
            v-loading="msgListLoading"
            class="loading-tip"
          >
          </span>
          <template v-if="getCurrentMsgList && getCurrentMsgList.length > 0">
            <div v-for="(msg, index) of getCurrentMsgList" :key="msg.msgKey">
              <!-- 文字消息 1 -->
              <template v-if="msg.contentType === 1">
                <ChatTimeLine
                  :time="msg.time"
                  v-if="
                    index === 0 || msg.time - getCurrentMsgList[index - 1]?.time > 50000
                  "
                />
                <ChatText :msg="msg" />
              </template>
              <!-- 图片消息 2-->
              <template v-if="msg.contentType === 2">
                <ChatTimeLine
                  :time="msg.time"
                  v-if="
                    index === 0 || msg.time - getCurrentMsgList[index - 1]?.time > 50000
                  "
                />
                <ChatImg :msg="msg" />
              </template>
              <!-- 小提示文字消息 4 -->
              <template v-if="msg.contentType === 4">
                <ChatOrderTips :text="msg.content" color="rgba(25,30,40,0.32)" />
              </template>
              <!-- 视频消息 5-->
              <template v-if="msg.contentType === 5">
                <ChatTimeLine
                  :time="msg.time"
                  v-if="
                    index === 0 || msg.time - getCurrentMsgList[index - 1]?.time > 50000
                  "
                />
                <ChatVideo :msg="msg" />
              </template>
              <!-- 文件消息 6-->
              <template v-if="msg.contentType === 6">
                <ChatTimeLine
                  :time="msg.time"
                  v-if="
                    index === 0 || msg.time - getCurrentMsgList[index - 1]?.time > 50000
                  "
                />
                <ChatFile :msg="msg" />
              </template>
              <!-- 加价消息 7-->
              <template v-if="msg.contentType === 7">
                <ChatTimeLine
                  :time="msg.time"
                  v-if="
                    index === 0 || msg.time - getCurrentMsgList[index - 1]?.time > 50000
                  "
                />
                <ChatInvite :msg="msg" />
              </template>
              <!-- 分享商品 8-->
              <template v-if="msg.contentType === 8">
                <ChatTimeLine
                  :time="msg.time"
                  v-if="
                    index === 0 || msg.time - getCurrentMsgList[index - 1]?.time > 50000
                  "
                />
                <ChatGoods :msg="msg" />
              </template>
            </div>
          </template>

          <!-- <ChatOrder />
          <ChatOrderTips
            text="买家已拒绝订单支付邀请"
            color="rgba(25,30,40,0.32)"
          />
          <ChatOrderTips text="买家已接受订单支付邀请" color="#019A81" />
          <ChatSendGoods />
          <ChatOrderMsg />
          <ChatGraphText />
          <ChatOrderTips
            text="买家已拒绝订单支付邀请"
            color="rgba(25, 30, 40, 0.32)"
            to="前往查看"
          /> -->
        </div>
        <div class="chat-tool" v-loading="uploading">
          <div class="tools-btn">
            <span @click="emojBoxShow = true">
              <img src="@/assets/chat-tools-1.png" alt="" />
              <div class="emoj-tip" v-if="emojBoxShow">
                <EmojBox @selectEmoj="selectEmoj" />
              </div>
            </span>
            <span @click="selectFile(2)"
              ><img src="@/assets/chat-tools-2.png" alt=""
            /></span>
            <span @click="selectFile(5)"
              ><img src="@/assets/chat-tools-3.png" alt=""
            /></span>
            <span @click="selectFile(6)"
              ><img src="@/assets/chat-tools-4.png" alt=""
            /></span>
          </div>
          <div>
            <el-input
              v-model="msgText"
              type="textarea"
              class="msg-input"
              contenteditable="true"
              @keydown="handleKeydown"
              ref="msgInputRef"
              :rows="5"
              placeholder="输入消息内容"
            ></el-input>
            <p class="send-msg">
              <button @click="sendMessage">
                <el-icon><Promotion /></el-icon>发送
              </button>
            </p>
          </div>
        </div>
      </div>
      <div
        class="chat-goods"
        v-if="
          getCurrentTalkInfo &&
          getCurrentTalkInfo.userType !== 4 &&
          getCurrentTalkInfo.userName !== '技能猴子官方'
        "
      >
        <div class="user-info">
          <el-image
            class="head"
            v-if="skillInfo.buyerUserId"
            :src="skillInfo.avatar"
            alt=""
          >
            <template #error>
              <img class="head" :src="defaultHead" alt="" />
            </template>
          </el-image>
          <div class="info">
            <p class="name">{{ skillInfo.nickName }}</p>
            <p class="rate">{{ skillInfo.companyName || "-" }}</p>
          </div>
        </div>
        <div class="acc-info">
          <p>
            <span class="label">何时加入</span>
            <span class="value" v-if="skillInfo.registerTime">{{
              skillInfo.registerTime.substr(0, 10)
            }}</span>
          </p>
          <p>
            <span class="label">买家评分</span>
            <span class="value"
              ><img src="@/assets/mack-icon.png" alt="" /><span class="rate">{{
                skillInfo.score || "0"
              }}</span>
              <!-- <span class="num">(82)</span>-->
            </span>
          </p>
          <router-link class="to-user-home" to="#">查看买家主页 ></router-link>
          <button class="phone-call">
            <img src="@/assets/phone.png" alt="" />
            电话联系
          </button>
        </div>
        <div class="service-list">
          <h4>我的服务</h4>
          <div
            class="service-item"
            v-for="item of goodsList"
            :key="item.goodsId"
            @click="goGoodsDetail(item.goodsId)"
          >
            <el-image class="cover-img" :src="item.coverPic" alt="" />
            <div class="info">
              <p class="title">{{ item.goodsName }}</p>
              <p class="price">
                ￥{{ item.goodsAmount }}
                <span @click="sendToCurrentChat(item)">发送服务</span>
              </p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.window {
  flex: 1;
  display: flex;
  flex-direction: column;
}
.chat-header {
  height: 80px;
  display: flex;
  align-items: center;
  padding: 0 24px;
  box-shadow: inset 0px -1px 0px 0px #ededee;
  .head {
    margin-right: 8px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
  }
  .info {
    flex: 1;
    display: flex;
    flex-direction: column;
    .name {
      color: #191e28;
      font-weight: bold;
      margin-bottom: 2px;
    }
    .online {
      color: #1dbf73;
    }
    .offline {
      color: rgba(25, 30, 40, 0.48);
    }
  }
  .tool-menu {
    position: relative;
    font-size: 8px;
    cursor: pointer;
    color: #191e28;
    .menu {
      position: absolute;
      top: 24px;
      right: -5px;
      width: 98px;
      height: 80px;
      background: #ffffff;
      box-shadow: 0px 0px 16px 0px rgba(11, 13, 18, 0.06);
      border-radius: 6px 6px 6px 6px;
      border: 1px solid rgba(25, 30, 40, 0.08);
      display: flex;
      flex-direction: column;
      padding: 2px 0;
      span {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 12px;
        &:hover {
          background: rgba(25, 30, 40, 0.02);
          margin: 0 2px;
          border-radius: 6px 6px 6px 6px;
        }
        img {
          width: 24px;
          height: 24px;
          margin-right: 4px;
        }
      }
    }
  }
}
.chat-box {
  flex: 1;
  display: flex;
}
.chat-left {
  flex: 1;
  border-right: 1px solid #ededee;
  display: flex;
  flex-direction: column;
  .chat-view {
    overflow-y: auto;
    padding: 20px;
    box-sizing: border-box;
    background: rgba(25, 30, 40, 0.01);
    height: calc(100vh - 320px);
    position: relative;
    .loading-tip {
      width: 100%;
      height: 40px;
      margin: 0 auto;
      display: block;
      width: 100%;
      text-align: center;
      position: absolute;
      top: 0;
      left: 0;
    }
  }
  .chat-tool {
    flex: 1;
    border-top: 1px solid #ededee;
    .tools-btn {
      display: flex;
      align-items: center;
      padding: 0 20px;
      height: 40px;
      box-sizing: border-box;
      border-bottom: 1px solid #ededee;
      span {
        position: relative;
      }
      img {
        cursor: pointer;
        width: 20px;
        height: 20px;
        margin-right: 16px;
      }
    }
    .send-msg {
      text-align: right;
      button {
        width: 80px;
        height: 32px;
        background: #1dbf73;
        border-radius: 8px 8px 8px 8px;
        border: none;
        cursor: pointer;
        color: #fff;
        margin-right: 16px;
        margin-top: 5px;
        i {
          vertical-align: -3px;
          margin-right: 4px;
        }
      }
    }
  }
}
.chat-goods {
  flex: 0 0 240px;
  padding: 20px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  .user-info {
    display: flex;
    align-items: center;
    margin-bottom: 16px;
    .head {
      width: 40px;
      height: 40px;
      margin-right: 8px;
      border-radius: 50%;
    }
    .name {
      color: #191e28;
      font-weight: bold;
      margin-bottom: 2px;
    }
    .rate {
      font-size: 12px;
      color: rgba(25, 30, 40, 0.48);
      span {
        color: #1dbf73;
        font-weight: bold;
      }
    }
  }
  .acc-info {
    display: flex;
    flex-direction: column;
    padding-bottom: 16px;
    border-bottom: 1px solid rgba(25, 30, 40, 0.08);
    p {
      display: flex;
      margin-bottom: 8px;
      font-size: 12px;
      color: #191e28;
      .label {
        flex: 1;
      }
      .value {
        display: flex;
        align-items: center;
        img {
          width: 12px;
          height: 12px;
        }
        .rate {
          font-weight: bold;
          margin: 0 4px;
        }
        .num {
          font-weight: bold;
          color: rgba(25, 30, 40, 0.48);
        }
      }
    }
    .to-user-home {
      font-size: 12px;
      color: #019a81;
      margin-bottom: 16px;
      text-decoration: none;
    }
    .phone-call {
      width: 200px;
      height: 36px;
      background: #ffffff;
      border-radius: 8px 8px 8px 8px;
      border: 1px solid #019a81;
      display: flex;
      align-items: center;
      justify-content: center;
      color: #019a81;
      img {
        width: 12px;
        height: 12px;
        position: relative;
        top: 2px;
        margin-right: 4px;
      }
    }
  }
  .service-list {
    flex: 1;
    overflow-y: auto;
    h4 {
      color: #191e28;
      padding: 16px 0 12px;
    }
    .service-item {
      display: flex;
      align-items: center;
      margin-bottom: 12px;
      img {
        width: 60px;
        height: 40px;
        border-radius: 4px;
        margin-right: 8px;
      }
      .info {
        flex: 1;
      }
      p {
        flex: 1;
        color: #191e28;
        font-size: 13px;
        line-height: 20px;
        // 超出两行显示省略号
        overflow: hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
      }
    }
  }
}
.service-list {
  flex: 1;
  overflow-y: auto;
  h4 {
    color: #191e28;
    padding: 16px 0 12px;
  }
  .service-item {
    display: flex;
    align-items: center;
    margin-bottom: 12px;
    cursor: pointer;
    .cover-img {
      width: 60px;
      height: 40px;
      border-radius: 4px;
      margin-right: 8px;
    }
    .info {
      flex: 1;
    }
    p {
      flex: 1;
      color: #191e28;
      font-size: 13px;
      line-height: 20px;
      // 超出两行显示省略号
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      &.price {
        display: flex;
        align-items: center;
        justify-content: space-between;
        span {
          cursor: pointer;
          font-size: 12px;
          background: #1dbf73;
          color: #fff;
          padding: 1px 6px;
          border-radius: 2px;
        }
      }
    }
  }
}
</style>

<style>
.window .el-textarea__inner {
  border: none !important;
  box-shadow: none;
  resize: none;
}
</style>
